import json

from flask import make_response, jsonify
from flask_appbuilder import ModelView, expose, BaseView
from flask_appbuilder.fieldwidgets import Select2Widget
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder.urltools import get_filter_args

from app.models import SerialPortCategory, SerialPort, Tray, Profile, Condition, CheckUnit
from wtforms.ext.sqlalchemy.fields import QuerySelectField
from app import appbuilder, db


def tray_query():
    return db.session.query(Tray)


class ProfileView(ModelView):
    datamodel = SQLAInterface(Profile)

    list_columns = ['name', 'default_tray.name', 'readme']
    edit_form_extra_fields = {'default_tray': QuerySelectField('Something',
                                                               query_factory=tray_query,
                                                               widget=Select2Widget(extra_classes="readonly"))}

    show_template = 'Profile/show_cascade.html'
    add_template = 'Profile/add.html'
    edit_template = 'Profile/edit.html'


class TrayView(ModelView):
    datamodel = SQLAInterface(Tray)
    related_views = [ProfileView]


class ProfileExtraDataView(BaseView):
    route_base = "/profile"

    @expose("/selectors")
    def selectors(self):
        # http://127.0.0.1:8000/profile/selectors?_flt_0_profile=1
        datamodel = SQLAInterface(Condition, appbuilder.session)
        _base_filters = datamodel.get_filters()
        list_cols = datamodel.get_columns_list()
        search_columns = datamodel.get_search_columns_list()
        _filters = datamodel.get_filters(search_columns)
        # _filters.clear_filters()
        # _filters.add_filter_index('profile', 0, '1')
        get_filter_args(_filters)
        joined_filters = _filters.get_joined_filters(_base_filters)
        order_column, order_direction = '', ''
        count, lst = datamodel.query(joined_filters, order_column, order_direction)
        # convert structure
        map_id_selector = dict()
        map_id_conditions = dict()
        for item in lst:
            selector_id = item.selector.id
            map_id_selector[selector_id] = item.selector
            conditions = map_id_conditions.get(selector_id)
            if conditions is None:
                conditions = []
                map_id_conditions[selector_id] = conditions
            conditions.append(item)
        # output final json
        ret_json = []
        for selector_id in map_id_selector.keys():
            selector = map_id_selector.get(selector_id)
            item = dict()
            item['selector.id'] = selector_id
            item['selector.name'] = selector.name
            item['selector.weight'] = selector.weight
            item['selector.tray'] = selector.tray.name
            item['selector.resister_a'] = selector.resister_a.name
            item['selector.resister_b'] = selector.resister_b.name
            # out conditions
            conditions = map_id_conditions.get(selector_id)
            conditions.sort(key=lambda x: x.unit_id)
            lst = []
            for c in conditions:
                data = dict()
                data['id'] = c.id
                data['name'] = c.name
                data['unit.id'] = c.unit_id
                data['unit.name'] = c.unit.name
                data['selector.id'] = selector_id
                data['voltage_a'] = c.voltage_a.name
                data['voltage_b'] = c.voltage_b.name
                data['readme'] = c.readme
                lst.append(data)
            item['conditions'] = lst
            ret_json.append(item)
        ret_json = jsonify(result=ret_json)
        response = make_response(ret_json, 200)
        response.headers['Content-Type'] = "application/json"
        return response

    @expose("/units")
    def units(self):
        # http://127.0.0.1:8000/profile/units?_flt_0_profile=1
        datamodel = SQLAInterface(CheckUnit, appbuilder.session)
        _base_filters = datamodel.get_filters()
        list_cols = datamodel.get_columns_list()
        search_columns = datamodel.get_search_columns_list()
        _filters = datamodel.get_filters(search_columns)
        # _filters.clear_filters()
        # _filters.add_filter_index('profile', 0, '1')
        get_filter_args(_filters)
        joined_filters = _filters.get_joined_filters(_base_filters)
        order_column, order_direction = 'id', 'asc'
        count, lst = datamodel.query(joined_filters, order_column, order_direction)
        # output final json
        ret_json = []
        for item in lst:
            data = dict()
            data['id'] = item.id
            data['name'] = item.name
            data['black'] = item.black.name
            data['temp'] = item.temp
            data['readme'] = item.readme
            ret_json.append(data)
        ret_json = jsonify(result=ret_json)
        response = make_response(ret_json, 200)
        response.headers['Content-Type'] = "application/json"
        return response


appbuilder.add_view(ProfileView, "Profiles", icon="fa-folder-open-o", category="Company")
appbuilder.add_view(TrayView, "Trays", icon="fa-folder-open-o", category="Company")
appbuilder.add_view_no_menu(ProfileExtraDataView)
